﻿using AutoMapper;
using Common.MyCustomException;
using Common.Result;
using IService;
using Model.Dto.Dish;
using Model.Entitys;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class DishService : IDishService
    {
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;
        public DishService(ISqlSugarClient db,IMapper mapper)
        {
            _db = db;
            _mapper = mapper;
        }
        /// <summary>
        /// 新增菜品，同时保存对应的口味数据
        /// </summary>
        /// <param name="dishAdd"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> SaveWithFlavorAsync(DishAdd dishAdd, long id)
        {
            //开启事务
            _db.Ado.BeginTran();
            var dish = _mapper.Map<Dish>(dishAdd);
            //设置默认状态
            dish.Status = 1;
            dish.CreateUser = id;
            dish.UpdateUser = id;
            //保存菜品的基本信息到菜品表dish
            var dishId = await _db.Insertable(dish).ExecuteReturnSnowflakeIdAsync();
            await InsertDishFlavorAsync(dishAdd.flavors, id, dishId);
            //提交事务
            _db.Ado.CommitTran();
            return true;
        }
        /// <summary>
        /// 根据ids逻辑删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> DeleteDishByIdsAsync(List<long> ids)
        {
            //先删除口味信息
            var res=await _db.Deleteable<Dish>()
                .EnableQueryFilter()
                .In(ids).IsLogic().ExecuteCommandAsync();
            //var res = await _db.Deleteable<DishFlavor>()
            //    .EnableQueryFilter()
            //    .In(ids).IsLogic().ExecuteCommandAsync();
            if (res>0) return true;
            return false;
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> EditDishByIdAsync(DishDto dishDto, long id)
        {
            _db.Ado.BeginTran();
            Dish dish = _mapper.Map<Dish>(dishDto);
            dish.UpdateUser = id;
            //先删除DishFlavor表口味信息 非逻辑删除
            await _db.Deleteable<DishFlavor>(dishDto.flavors).ExecuteCommandAsync();
            //更新忽略null并且忽略默认值
            var updateDish= await _db.Updateable(dish).IgnoreColumns(ignoreAllNullColumns: true, ignoreAllDefaultValue: true)
                .Where(it => it.Id == dish.Id).ExecuteCommandAsync();
            //重新插入DishFlavor表口味信息
            var insertFlavir=await InsertDishFlavorAsync(dishDto.flavors, id,dish.Id);
            if (insertFlavir.Count > 0 && updateDish > 0)
            {
                //提交事务
                _db.Ado.CommitTran();
                return true;
            }
            return false;
            
        }
        /// <summary>
        /// 根据ids修改状态
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> EditStatusByIdsAsync(List<long> ids,int status, long userId)
        {
            _db.Ado.BeginTran();//开启事务
            // 将 ids 的值赋给 dishes 集合的 id 属性
            List<Dish> dishes = ids.Select(id => new Dish { Id = id }).ToList();
            //同时赋值status
            dishes.ForEach(d => { d.UpdateUser = userId; d.Status = status; });
            //只更新status
            var col = await _db.Updateable(dishes).UpdateColumns(it => new { it.Status, it.UpdateTime,it.UpdateUser })
                .ExecuteCommandAsync();
            _db.Ado.CommitTran();//提交事务
            if (col>0) return true;
            return false;
        }

        /// <summary>
        /// 根据id查询菜品信息和对应的口味信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<DishDto> GetDishDtoByTdAsync(long id)
        {
            DishDto dishDto = await _db.Queryable<Dish>().LeftJoin<Category>((d, cate) => d.CategoryId == cate.Id)
                .Where((d, cate) => d.Id == id)
                .Select((d, cate) => new DishDto
                {
                    Id = d.Id,
                    Name = d.Name,
                    CategoryName = cate.Name,
                    CategoryId = cate.Id,
                }, true)//其余字段自动映射
                .FirstAsync();
            dishDto.flavors = await _db.Queryable<DishFlavor>().Where(it => it.DishId == id).ToListAsync();
            return dishDto;
        }

        /// <summary>
        /// 分页查询联合分类表
        /// </summary>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PageInfo> GetPageInfoAsync(int page, int pageSize, string? name)
        {
            RefAsync<int> total = 0;
            //联合category表查询分类名
            var dishs = await _db.Queryable<Dish>()
                              .LeftJoin<Category>((d, cate) => d.CategoryId == cate.Id)
                              .WhereIF(!string.IsNullOrEmpty(name), (d, cate) => d.Name.Contains(name))
                              .Select((d, cate) => new DishDto{
                                  Id=d.Id,
                                  Name=d.Name,
                                  CategoryName = cate.Name
                              },true)//其余字段自动映射
                              .ToPageListAsync(page, pageSize, total);
            return new PageInfo
            {
                Data = dishs,
                Total = total
            };
        }

        /// <summary>
        /// 插入DishFlavor方法
        /// 
        /// </summary>
        /// <param name="dishAdd"></param> List<DishFlavor>
        /// <param name="id"></param> 操作人
        /// <param name="dishId"></param> 菜品id
        /// <returns></returns>
        private async Task<List<long>> InsertDishFlavorAsync(List<DishFlavor> flavors, long id, long dishId)
        {
            //设置dishId和user
            foreach (var item in flavors)
            {
                item.DishId = dishId;
                item.CreateUser = id;
                item.UpdateUser = id;
            }
            //dishAdd.flavors.ForEach(flavor => flavor.DishId = dishId)

            //保存菜品口味数据到菜品口味表dish_flavor
             return await _db.Insertable(flavors).ExecuteReturnSnowflakeIdListAsync();
        }
        /// <summary>
        /// 根据条件查询对应的菜品数据
        /// </summary>
        /// <param name="dish"></param>
        /// <returns></returns>
        //public async Task<List<Dish>> GetDishes(Dish dish)
        //{
        //    var res=await _db.Queryable<Dish>().Where(it=>it.CategoryId == dish.CategoryId && it.Status==1)
        //        .OrderBy(it=>it.Sort).OrderBy(it=>it.UpdateTime, OrderByType.Desc)
        //        .ToListAsync();
        //    return res;
        //}
        public async Task<List<DishDto>> GetDishesAsync(DishQuery dishQuery)
        {
            //var DishDtoes = await _db.Queryable<Dish>()
            //    .LeftJoin<Category>((d, cate) => d.CategoryId == cate.Id)
            //    .LeftJoin<DishFlavor>((d, cate, flavor) => d.Id == flavor.DishId)
            //    .Where((d, cate, flavor) => d.CategoryId == dishQuery.CategoryId )
            //    .WhereIF(dishQuery.Status!=null, (d, cate, flavor) =>d.Status == dishQuery.Status)
            //    .OrderBy((d, cate, flavor) => d.Sort).OrderBy((d, cate, flavor) => d.UpdateTime, OrderByType.Desc)
            //    .Select((d, cate, flavor) => new DishDto
            //    {
            //        Id = d.Id,
            //        CategoryName = cate.Name,
            //        Name = d.Name
            //    }, true)// 其余字段自动映射
            //    .ToListAsync();
            var DishDtoes = await _db.Queryable<Dish>()
                .LeftJoin<Category>((d, cate) => d.CategoryId == cate.Id)
                .Where((d, cate) => d.CategoryId == dishQuery.CategoryId)
                .WhereIF(dishQuery.Status != null, (d, cate) => d.Status == dishQuery.Status)
                .OrderBy((d, cate) => d.Sort).OrderBy((d, cate) => d.UpdateTime, OrderByType.Desc)
                .Select((d, cate) => new DishDto
                {
                    Id = d.Id,
                    CategoryName = cate.Name,
                    Name = d.Name
                }, true)// 其余字段自动映射
                .ToListAsync();
            foreach (var item in DishDtoes)
            {
                item.flavors = await _db.Queryable<DishFlavor>().Where(it => it.DishId == item.Id).ToListAsync();
            }
            return DishDtoes;
        }
    }
}
